package com.tn.socket;

import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.tomcat.util.threads.ThreadPoolExecutor;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.TimeUnit;

/**
 * @ClassName TestRunner
 * @Description TODO
 * @Author Yezhongzhu
 * @Date 2021/12/30 10:40
 * @Version v1.0
 **/
@Component
@Slf4j
public class SocketPoolRunner { //implements CommandLineRunner, InitializingBean {
//public class SocketPoolRunner implements CommandLineRunner, InitializingBean {
    @Value("${project.startup.mptest:}")
    String startUpMpTest;

    @Resource
    private SocketProperties properties;

    private ServerSocket ss = null;

    public static  List<CardSendRobot> clients = new ArrayList<CardSendRobot>();

    private ThreadPoolExecutor pool =null;

    /**
     * 发卡机服务端启动方法
     * @param args
     * @throws Exception
     */
//    @Override
    public void run(String... args) throws Exception {
        if(startUpMpTest.equals("test") || StrUtil.isNotBlank(startUpMpTest)) {
            return;
        }
        ServerSocket server = null;
        server = new ServerSocket(properties.getPort());
        log.info("设备服务器已经开启, 监听端口:" + properties.getPort());
        try {
            while (true) {
                Socket socket = server.accept();
                if(null!=socket){
                    CardSendRobot serverAcceptMessage= new CardSendRobot(socket);
                    clients.add(serverAcceptMessage);
                    pool.execute(serverAcceptMessage);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                ss.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

//    @Override
    public void afterPropertiesSet() throws Exception {
        pool = new ThreadPoolExecutor(
                properties.getPoolCore(),
                properties.getPoolMax(),
                properties.getPoolKeep(),
                TimeUnit.SECONDS,
                new ArrayBlockingQueue<Runnable>(properties.getPoolQueueInit()),
                new ThreadPoolExecutor.DiscardOldestPolicy()
        );
    }
}
